# tts_service.py
import os
import tempfile
import logging
from typing import Optional

logger = logging.getLogger(__name__)

class TTSService:
    def __init__(self):
        # 尝试从环境变量获取 Azure TTS 密钥
        self.azure_key = os.getenv("AZURE_TTS_KEY")
        self.region = os.getenv("AZURE_TTS_REGION", "eastasia")
        self.voice_options = {
            "female": "zh-CN-XiaoxiaoNeural",
            "male": "zh-CN-YunxiNeural",
            "female_calm": "zh-CN-XiaoyiNeural",
            "male_narration": "zh-CN-YunxiNeural",
            "child": "zh-CN-XiaobeiNeural"
        }
        
        # 如果没有 Azure 密钥，使用备用方案
        self.use_fallback = not self.azure_key
        
    def generate_speech(self, text: str, voice_type: str = "female", output_file: Optional[str] = None):
        """生成语音"""
        if output_file is None:
            output_file = tempfile.mktemp(suffix='.wav')
        
        if not self.use_fallback:
            return self._azure_tts(text, voice_type, output_file)
        else:
            # 使用备用 TTS 方案，如使用 gTTS
            return self._fallback_tts(text, voice_type, output_file)
    
    def _azure_tts(self, text: str, voice_type: str, output_file: str):
        """使用 Azure TTS 生成语音"""
        try:
            import azure.cognitiveservices.speech as speechsdk
        except ImportError:
            logger.warning("未安装 azure-cognitiveservices-speech，使用备用方案")
            return self._fallback_tts(text, voice_type, output_file)
        
        try:
            # 创建 speech config
            speech_config = speechsdk.SpeechConfig(subscription=self.azure_key, region=self.region)
            speech_config.speech_synthesis_voice_name = self.voice_options.get(voice_type, self.voice_options["female"])
            
            # 设置音频输出
            audio_config = speechsdk.audio.AudioOutputConfig(filename=output_file)
            
            # 创建 speech synthesizer
            synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=audio_config)
            
            # 生成语音
            result = synthesizer.speak_text_async(text).get()
            
            # 检查结果
            if result.reason == speechsdk.ResultReason.SynthesizingAudioCompleted:
                logger.info(f"语音生成成功: {output_file}")
                return output_file
            else:
                logger.error(f"语音生成失败: {result.reason}")
                # 尝试使用取消静音来获取错误详情
                cancellation_details = result.cancellation_details
                if cancellation_details.reason == speechsdk.CancellationReason.Error:
                    logger.error(f"错误详情: {cancellation_details.error_details}")
                return None
                
        except Exception as e:
            logger.error(f"Azure TTS 生成失败: {e}")
            # 回退到备用方案
            return self._fallback_tts(text, voice_type, output_file)
    
    def _fallback_tts(self, text: str, voice_type: str, output_file: str):
        """使用备用 TTS 方案生成语音"""
        try:
            from gtts import gTTS
            
            # 限制文本长度
            if len(text) > 1000:
                text = text[:1000] + "..."
            
            # 确定语言
            lang = 'zh' if voice_type.startswith('zh') or 'CN' in voice_type else 'en'
            
            # 创建 TTS 对象
            tts = gTTS(text=text, lang=lang, slow=False)
            
            # 保存到文件
            tts.save(output_file)
            
            logger.info(f"备用语音生成成功: {output_file}")
            return output_file
            
        except ImportError:
            logger.error("未安装 gtts，请运行: pip install gtts")
            return None
        except Exception as e:
            logger.error(f"备用 TTS 生成失败: {e}")
            return None
    
    def batch_generate_speech(self, texts: list, voice_type: str = "female"):
        """批量生成语音"""
        output_files = []
        for i, text in enumerate(texts):
            output_file = tempfile.mktemp(suffix=f'_{i}.wav')
            result = self.generate_speech(text, voice_type, output_file)
            if result:
                output_files.append(result)
            else:
                logger.error(f"第 {i+1} 个语音生成失败")
        return output_files
